package com.firesrc.mail.thread;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import jodd.db.DbThreadSession;
import jodd.db.oom.DbOomQuery;

import com.firesrc.bean.MailDayAmount;
import com.firesrc.bean.Record;
import com.firesrc.db.DBManager;
import com.firesrc.mail.send.MailSendManagerFactory;
import com.firesrc.mail.send.MailSender;
import com.firesrc.service.MailDayAmountService;
import com.firesrc.service.impl.MailDayAmountServiceImpl;
import com.firesrc.util.SystemUtil;

public class SendMailCompleteNewExecutor {
	private static ExecutorService executor = Executors.newFixedThreadPool(5);

	public static void main(String[] args) throws Throwable {
		SendMailCompleteNewExecutor completeExecutor = new SendMailCompleteNewExecutor();
		completeExecutor.execute();
		executor.shutdown();
	}

	public void execute() throws Throwable {
		MailSendManagerFactory managerFactory = new MailSendManagerFactory();
		final List<MailSender> mailSenderList = managerFactory.getList();
		CompletionService<MailSender> completionService = new ExecutorCompletionService<MailSender>(executor);
		DbThreadSession dbThreadSession = new DbThreadSession(DBManager.getPublicConnectionPool());
		DbOomQuery q = new DbOomQuery("select top 300 * from record where mailstate is null and mail is not null");
		List<Record> recordList = q.list(Record.class);
		ConcurrentLinkedQueue<Record> recordQueue = new ConcurrentLinkedQueue<Record>();

		for (Record record : recordList) {
			recordQueue.add(record);
		}
		System.out.println("一次最多发送邮件为:" + recordQueue.size());
		System.out.println("用来发送 邮箱共有:" + mailSenderList.size() + "个邮箱进行发送");
		for (final MailSender mailSender : mailSenderList)
			completionService.submit(new CallTask(mailSender, recordQueue));

		dbThreadSession.closeSession();
		System.out.println("SendMailThread.run() 开始发邮件:" + new Date());
		MailDayAmountService service = new MailDayAmountServiceImpl();
		try {
			for (int t = 0, n = mailSenderList.size(); t < n; t++) {
				Future<MailSender> f = completionService.take();
				MailSender mailSender = f.get();
				if (mailSender != null) {
					MailDayAmount mailDayAmount = new MailDayAmount();
					mailDayAmount.setId(UUID.randomUUID().toString());
					mailDayAmount.setUserName(mailSender.getMail());
					int alreadyDayCount = mailSender.getAlreadyDayCount();
					mailDayAmount.setAmount(alreadyDayCount);
					mailDayAmount.setKind(mailSender.getKind());
					mailDayAmount.setSendDate(SystemUtil.getCurrentDateYYYYMMDD());
					if (mailSender.getAlreadyDayCount() >= mailSender.getMaxDayCount()) {
						mailDayAmount.setState("1");
					} else {
						mailDayAmount.setState("0");
					}
					System.out.println(mailDayAmount.getUserName() + "插入Amount前数量" + mailDayAmount.getAmount());
					if (alreadyDayCount > 0) {
						service.put(mailDayAmount);
					}
				}
			}
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
		} catch (ExecutionException e) {
			throw new Throwable(e.getCause());
		}
		System.out.println("SendMailCompleteExecutor.execute()  邮件发送完成");
	}

	private final class CallTask implements Callable<MailSender> {
		private final MailSender mailSender;
		private final ConcurrentLinkedQueue<Record> recordQueue;

		private CallTask(MailSender mailSender, ConcurrentLinkedQueue<Record> recordQueue) {
			this.mailSender = mailSender;
			this.recordQueue = recordQueue;
		}

		public MailSender call() {
			mailSender.openSession();
			mailSender.batchSendMail(recordQueue);
			return mailSender;
		}
	}

}
